package view;

import java.awt.*;
import java.rmi.registry.Registry;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;

import util.Controller;

public class Zombie extends JLabel implements Runnable, Comparable{

    private int x;
    private int y;
    private int level;
    private int minx = -300;
    private int life = 100;
    private int r;
    private int c;
    private int pic;
    private int [] allPic = new int[4];
    private int type;
    private int state =1;
    private int flag = 1 ;
    private int strength;
    private Controller controller;
    private Plant [][]plants = new Plant[5][9];
	private Image image;
    private Image offScreenImage;
    
    Zombie(Controller controller,int r){
    	this.controller = controller;
    	plants = controller.getPlants();
        this.r = r;
        this.x = 800;//680;
        this.y =  r*100+28;
        this.strength=0;
        controller.getLayeredPane().add(this,new Integer(120+r));
        this.pic = 0;
        type = (int) (Math.random()*3)+1;
        allPic[1] = 21;
        allPic[2] = 30;
        allPic[3] = 17;
    }

    public int getR() {
        return r;
    }
    
    public int getLife() {
		return life;
	}


	@Override
    public int getX() {
        return x;
    }

    public void setPic(int pic) {
		this.pic = pic;
	}

	public void setState(int state) {
		this.state = state;
	}

    public void normalpicChange(){
        if (pic < allPic[type])
            pic++;
        else
            pic = 0;
    }   

	public void hurtpicChange() {
        if (pic < 17 )
            pic++;
        else
            pic = 0;
	}

	public void boompicChange() {
        if (pic < 19)
            pic++;
        else
            pic = 0;
		
	}

    public void picChange() {
        if (pic < 13 )
            pic++;
        else
            pic = 0;
	}   
    
    public void normalAttackChange() {
        if (pic < 20 )
            pic++;
        else
            pic = 0;
	}   
    
    public void hurtAttackChange() {
        if (pic < 9 )
            pic++;
        else
            pic = 0;
	} 
    
    public boolean havaPlants() {
    	c = -1;
    	for(int j = (this.x+20)/80 ; j >= 0 ; j-- ) {
    		if( j>8 ) {
    			continue;
    		}
    		if( plants[r][j] != null ) {
    			c = j;
    			break;
    		}
    	}
    	int dis = this.x-c*80;
    	if(Math.abs(dis)<=20 && c!=-1) 
    		return true;
    	return false;
    }
    
    public boolean isAlive() {
    	if(this.life>=0)
    		return true;
    	else
    		return false;
    }
    
    public void gatherStrength(){
        this.strength ++;
    }
    
    public void resetState(int  state) {
		this.state=state;
		this.setPic(0);
		this.setState(state);
    }
    
    @Override
    public int compareTo(Object o) {
        return this.x - ((Zombie)o).getX();
    }

	public void getHurt() {
		this.life-=10;
		System.out.println(this.life);
	}

	public void die() {
		this.life =0;
		this.resetState(7);
	}
	
	public void boomDie() {
		this.resetState(3);
	}
    
	@Override
    public void paintComponent(Graphics g) {
		
        super.paintComponent(g);
        ImageIcon img = new ImageIcon("img\\shadow.png");
        g.drawImage(img.getImage(), 70, 115,
                img.getIconWidth(), img.getIconHeight(), this);
        
        if(state == 1) {
            Graphics2D g2 = (Graphics2D) g;
        	img = new ImageIcon("Img\\Zombie"+type+"\\Frame"+pic+".png");
        	g2.drawImage(img.getImage(), 0, 0,
                    img.getIconWidth(), img.getIconHeight(),  this);
        }
        
        else if(state == 2) {
            img = new ImageIcon("Img\\ZombieLostHead\\Frame"+pic+".png");
            Graphics2D g2 = (Graphics2D) g;
            g2.drawImage(img.getImage(), 0, 0,img.getIconWidth(), img.getIconHeight(),  this);
			if(pic<10 && flag ==1) {
                img = new ImageIcon("Img\\ZombieHead\\Frame"+pic+".png");
                g2.drawImage(img.getImage(),60, 0,
                        img.getIconWidth(), img.getIconHeight(),  this);
                if(pic==9)
            	    flag=2;
            }
        }
        
        else if(state == 3) {
            img = new ImageIcon("Img\\boom\\Frame"+pic+".png");
            image = img.getImage();
            Graphics2D g2 = (Graphics2D) g;
            g2.drawImage(image, 0, -10, img.getIconWidth(), img.getIconHeight(),  this);  
        }
        
        else if(state == 4){
            img = new ImageIcon("Img\\ZombieDie\\Frame"+pic+".png");
            image = img.getImage();
            Graphics2D g2 = (Graphics2D) g;
            g2.drawImage(image, 0, 0, img.getIconWidth(), img.getIconHeight(),  this);  
        }
        
        else if(state == 5) {
            img = new ImageIcon("Img\\ZombieAttack\\Frame"+pic+".png");
            image = img.getImage();
            Graphics2D g2 = (Graphics2D) g;
            g2.drawImage(image, 0, 0, img.getIconWidth(), img.getIconHeight(),  this);  
        }
        
        else if (state == 6 ){
            img = new ImageIcon("Img\\ZombieLostHeadAttack\\Frame"+pic+".png");
            image = img.getImage();
            Graphics2D g2 = (Graphics2D) g;
            g2.drawImage(image, 0, 0, img.getIconWidth(), img.getIconHeight(),  this);  	
        }
        else if (state ==7 ) {
            img = new ImageIcon("Img\\ZombieDie\\Frame"+pic+".png");
            Graphics2D g2 = (Graphics2D) g;
            g2.drawImage(img.getImage(), 0, 0,img.getIconWidth(), img.getIconHeight(),  this);
			if(pic<10 && flag ==1) {
                img = new ImageIcon("Img\\ZombieHead\\Frame"+pic+".png");
                g2.drawImage(img.getImage(),60, 0, this);
                if(pic==9)
            	    flag=2;
            }
        }
    }
    
	
    public void update(Graphics g) {
        if(offScreenImage == null)
            offScreenImage = this.createImage(800, 600);
        Graphics gImage = offScreenImage.getGraphics();
        paint(gImage);
        g.drawImage(offScreenImage, 0, 0, null);
    }

   

    @Override
    public void run() {
    	
        this.setVisible(true);
        
        for (int i = 1 ; this.x> minx && this.state==1 ; i++){
       	
        	while(controller.isPause()) {
        		try {
					Thread.sleep(5);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
        	}
        	
        	if(this.havaPlants()) {	       		
        		this.resetState(5);      		
        		for(int j = 1; plants[r][c]!=null && plants[r][c].isAlive() && this.isAlive() ; j++) {
        			this.gatherStrength();
                    try {
            			if(plants[r][c].getHp()<=0) {
            				this.resetState(1);
            				plants[r][c].die();
            				plants[r][c] = null;
            				break;    				
            			}
                        if (j%11==0){
                            this.normalAttackChange();
                        }
                        this.setBounds(x,y,400,300);
                        Thread.sleep(8);
                        this.repaint();
                        if(this.strength==30) {
                            this.strength=0;
                            plants[r][c].getHurt();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
        		}
        	}
        	
            if(this.life<=50) {
            	this.resetState(2);
                break;
            }
            try {
                if (i%11==0){
                    this.normalpicChange();
                }
                this.setBounds(x,y,400,300);
                Thread.sleep(8);
                if (i%8==0){
                    this.x-=2;
                }
                this.repaint();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        for (int i=1 ; this.x> minx && this.state==2 ; i++){
        	while(controller.isPause()) {
        		try {
					Thread.sleep(5);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
        	}
        	if(this.havaPlants()) {
        		this.resetState(6);  		
        		for(int j = 1; plants[r][c]!=null && plants[r][c].isAlive() && this.isAlive(); j++) {
        			this.gatherStrength();
        			if(plants[r][c].getHp()<=0) {
        				this.resetState(2);
        				plants[r][c].die();
        				plants[r][c]=null;
        				break;    				
        			}
                    try {
                        if (j%11==0){
                            this.hurtAttackChange();
                        }
                        this.setBounds(x,y,400,300);
                        Thread.sleep(8);
                        this.repaint();
                        if(this.strength==40) {
                            this.strength=0;
                            plants[r][c].getHurt();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
        		}
        	}
            if(this.life<=0) {
            	this.resetState(4);
                break;
            }
            try {
                if (i%11==0){
                    this.hurtpicChange();
                }
                this.setBounds(x,y,400,300);
                Thread.sleep(8);
                if (i%7==0){
                    this.x-=1;
                }
                this.repaint();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        for (int i=1 ; pic<19 && state == 3 ; i++ ){
        	while(controller.isPause()) {
        		try {
					Thread.sleep(5);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
        	}
            try {
                if (i%8==0){
                    this.boompicChange();
                }
                Thread.sleep(7);
                this.repaint();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        if( state == 4 || state == 7) {
        	while(controller.isPause()) {
        		try {
					Thread.sleep(5);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
        	}
            for (int i=1 ; i<=104  ; i++){
                try {
                    if (i%8==0){
                        this.picChange();
                    }
                    Thread.sleep(10);
                    this.repaint();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }   
        }
        
        this.setVisible(false);
        controller.getZombieLists().get(r).remove(this);
    }
}
